/*
 *
 * Copyright(c) 2010 Safelayer Secure Communications
 *
 * This is open source software, placed under the terms of the
 * GNU GENERAL PUBLIC LICENSE Version 3.
 * Please see: http://www.gnu.org/licenses/gpl-3.0.txt
 * 
 * Permission to use, copy, modify, and distribute this software
 * for any purpose and without fee is hereby granted, provided
 * that the above copyright notices appear in all copies and that
 * both the copyright notice and this permission notice appear in
 * supporting documentation.
 * 
 */
package com.neuralnoise.foaf.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * Models a FOAF Agent. The <code>Agent</code> class is the class of agents; things that do stuff. A
 * well known sub-class is {@link Person}, representing people. Other kinds of agents include
 * Organization and {@link Group}.
 * <p>
 * For more info see the FOAF Vocabulary Specification
 * 
 * 
 * @author victor.martinez <swtp@safelayer.com>
 */
public class Agent extends Thing {

	private Set<Document> weblogSet = new LinkedHashSet<Document>();

	private Set<Thing> mboxSet = new LinkedHashSet<Thing>();

	private Set<String> mboxSha1SumSet = new LinkedHashSet<String>();

	private Set<OnlineAccount> holdsAccountSet = new LinkedHashSet<OnlineAccount>();

	private Set<Thing> madeSet = new LinkedHashSet<Thing>();

	private Set<String> skypeIDSet = new LinkedHashSet<String>();

	private Set<String> msnChatIDSet = new LinkedHashSet<String>();

	private Set<String> icqChatIDSet = new LinkedHashSet<String>();

	private Set<String> jabberIDSet = new LinkedHashSet<String>();

	private Set<String> yahooChatIDSet = new LinkedHashSet<String>();

	private Set<String> aimChatIDSet = new LinkedHashSet<String>();

	private Set<OnlineAccount> accountSet = new LinkedHashSet<OnlineAccount>();

	private Set<Document> openidSet = new LinkedHashSet<Document>();

	private Set<Document> tipJarSet = new LinkedHashSet<Document>();

	private Set<Thing> topicInterestSet = new LinkedHashSet<Thing>();

	private String status;

	private String birthday;

	private String age;

	private String gender;

	public Agent(String uri) {
		// call Thing constructor
		super(uri);
	}

	public Agent() {
		// call Thing constructor
		super(null);
	}

	/**
	 * Return all aimChatIDs.
	 * 
	 * @return Returns all aimChatIDs.
	 */
	public List<String> getAllAimChatIDs() {
		return new ArrayList<String>(aimChatIDSet);
	}

	/**
	 * Adds the specified <code>aimChatID</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param aimChatID The <code>aimChatID</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>aimChatID</code>
	 */
	public boolean addAimChatID(String aimChatID) {
		return aimChatIDSet.add(aimChatID);
	}

	/**
	 * Removes the specified aimChatID to this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contains the specified aimChatID (or equally,
	 * if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param value The aimChatID to be removed to this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified aimChatID
	 */
	public boolean removeAimChatID(String value) {
		return aimChatIDSet.remove(value);
	}

	/**
	 * Removes all of the aimChatIDs from this {@link Agent}. The aimChatIDs from<code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearAimChatIDs() {
		aimChatIDSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>aimChatID</code>.
	 * 
	 * @param aimChatID The <code>aimChatID</code> whose presence in this <code>Agent</code> is to
	 *            be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>aimChatID</code>
	 */
	public boolean containsAimChatID(String aimChatID) {
		return aimChatIDSet.contains(aimChatID);
	}

	/**
	 * @return the gender.
	 */
	public String getGender() {
		return gender;
	}

	/**
	 * @param gender The gender to set.
	 */
	public void setGender(String gender) {
		this.gender = gender;
	}

	/**
	 * Return all icqChatIDs.
	 * 
	 * @return Returns all icqChatIDs.
	 */
	public List<String> getAllIcqChatIDs() {
		return new ArrayList<String>(icqChatIDSet);
	}

	/**
	 * Adds the specified <code>icqChatID</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param icqChatID The <code>icqChatID</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>icqChatID</code>
	 */
	public boolean addIcqChatID(String icqChatID) {
		return icqChatIDSet.add(icqChatID);
	}

	/**
	 * Removes all icqChatIDs from this {@link Agent}. The icqChatIDs from<code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearIcqChatIDs() {
		icqChatIDSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>icqChatID</code>.
	 * 
	 * @param icqChatID The <code>icqChatID</code> whose presence in this <code>Agent</code> is to
	 *            be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>icqChatID</code>
	 */
	public boolean containsIcqChatID(String icqChatID) {
		return icqChatIDSet.contains(icqChatID);
	}

	/**
	 * Return all jabberIDs.
	 * 
	 * @return Returns all jabberIDs.
	 */
	public List<String> getAlljabberIDs() {
		return new ArrayList<String>(jabberIDSet);
	}

	/**
	 * Adds the specified <code>jabberID</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param jabberID The <code>jabberID</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>jabberID</code>
	 */
	public boolean addjabberID(String jabberID) {
		return jabberIDSet.add(jabberID);
	}

	/**
	 * Removes the specified jabberID frin this {@link Agent}, if it is present. Returns <tt>true</tt>
	 * if this <code>Agent</code> contained the specified jabberID (or equivalently, if this
	 * <code>Agent</code> changed as a result of the call).
	 * 
	 * @param value The jabberID to be removed to this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified jabberID
	 */
	public boolean removeJabberID(String value) {
		return jabberIDSet.remove(value);
	}

	/**
	 * Removes all of the jabberIDs from this {@link Agent}. The jabberIDs from <code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearjabberIDs() {
		jabberIDSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>jabberID</code>.
	 * 
	 * @param jabberID The <code>jabberID</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>jabberID</code>
	 */
	public boolean containsjabberID(String jabberID) {
		return jabberIDSet.contains(jabberID);
	}

	/**
	 * Return all topicInterest.
	 * 
	 * @return Returns all topicInterests.
	 */
	public List<Thing> getAllTopicInterests() {
		return new ArrayList<Thing>(topicInterestSet);
	}

	/**
	 * Adds the specified <code>topicInterest</code> to this {@link Agent} if it is not already
	 * present.
	 * 
	 * @param topicInterest The <code>topicInterest</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>topicInterest</code>
	 */
	public boolean addTopicInterest(Thing topicInterest) {
		return topicInterestSet.add(topicInterest);
	}

	/**
	 * Removes the specified <code>topicInterest</code> to this {@link Agent}, if it is present.
	 * Returns <tt>true</tt> if this <code>Agent</code> contained the specified
	 * <code>topicInterest</code> (or equivalently, if this <code>Agent</code> changed as a result
	 * of the call).
	 * 
	 * @param topicInterest The <code>topicInterest</code> to be removed to this <code>Agent</code>
	 * 
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified
	 *         <code>topicInterest</code>
	 */
	public boolean removeTopicInterest(Thing topicInterest) {
		return topicInterestSet.remove(topicInterest);
	}

	/**
	 * Removes all of the topicInterest from this {@link Agent}. The topicInterest from
	 * <code>Agent</code> will be empty after this call returns.
	 */
	public void clearTopicInterests() {
		topicInterestSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>topicInterest</code>
	 * 
	 * @param topicInterest The <code>topicInterest</code> whose presence in this <code>Agent</code>
	 *            is to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>topicInterest</code>
	 */
	public boolean containsTopicInterest(Thing topicInterest) {
		return topicInterestSet.contains(topicInterest);
	}

	/**
	 * Returns all mailboxes.
	 * 
	 * @return Returns all mailboxes.
	 */
	public List<Thing> getAllMboxes() {
		return new ArrayList<Thing>(mboxSet);
	}

	/**
	 * Adds the specified <code>mbox</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param mbox The <code>mbox</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>mbox</code>
	 */
	public boolean addMbox(Thing mbox) {
		return mboxSet.add(mbox);
	}

	/**
	 * Removes the specified <code>mbox</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>mbox</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param mbox The <code>mbox</code> to be removed from this <code>Agent</code>
	 * 
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>mbox</code>
	 */
	public boolean removeMbox(Thing mbox) {
		return mboxSet.remove(mbox);
	}

	/**
	 * Removes all of the mboxes from this {@link Agent}. The mboxes from <code>Agent</code> will be
	 * empty after this call returns.
	 */
	public void clearMboxes() {
		mboxSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>mbox</code>
	 * 
	 * @param mbox The <code>mbox</code> whose presence in this <code>Agent</code> is to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>mbox</code>
	 */
	public boolean containsMbox(Thing mbox) {
		return mboxSet.contains(mbox);
	}

	/**
	 * Returns all mboxesSha1Sum.
	 * 
	 * @return Returns all mboxesSha1Sum.
	 */
	public List<String> getAllMboxesSha1Sum() {
		return new ArrayList<String>(mboxSha1SumSet);
	}

	/**
	 * Adds the specified <code>mboxSha1Sum</code> to this {@link Agent} if it is not already
	 * present.
	 * 
	 * @param mboxSha1Sum The <code>mboxSha1Sum</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>mboxSha1Sum</code>
	 */
	public boolean addMboxSha1Sum(String mboxSha1Sum) {
		return mboxSha1SumSet.add(mboxSha1Sum);
	}

	/**
	 * Removes the specified <code>mboxSha1Sum</code> to this {@link Agent}, if it is present.
	 * Returns <tt>true</tt> if this <code>Agent</code> contained the specified
	 * <code>mboxSha1Sum</code> (or equivalently, if this <code>Agent</code> changed as a result of
	 * the call).
	 * 
	 * @param mboxSha1Sum The <code>mboxSha1Sum</code> to be removed to this <code>Agent</code>
	 * 
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified
	 *         <code>mboxSha1Sum</code>
	 */
	public boolean removeMboxSha1Sum(String mboxSha1Sum) {
		return mboxSha1SumSet.remove(mboxSha1Sum);
	}

	/**
	 * Removes all of the mboxesSha1Sum from this {@link Agent}. The mboxSha1Sums from
	 * <code>Agent</code> will be empty after this call returns.
	 */
	public void clearMboxesSha1Sum() {
		mboxSha1SumSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>mboxSha1Sum</code>.
	 * 
	 * @param mboxSha1Sum The <code>mboxSha1Sum</code> whose presence in this <code>Agent</code> is
	 *            to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>mboxSha1Sum</code>
	 */
	public boolean containsMboxSha1Sum(String mboxSha1Sum) {
		return mboxSha1SumSet.contains(mboxSha1Sum);
	}

	/**
	 * Returns all msnChatIDs.
	 * 
	 * @return Returns all msnChatIDs.
	 */
	public List<String> getAllMsnChatIDs() {
		return new ArrayList<String>(msnChatIDSet);
	}

	/**
	 * Adds the specified <code>msnChatID</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param msnChatID The <code>msnChatID</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>msnChatID</code>
	 */
	public boolean addMsnChatID(String msnChatID) {
		return msnChatIDSet.add(msnChatID);
	}

	/**
	 * Removes the specified <code>msnChatID</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>msnChatID</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param msnChatID The <code>msnChatID</code> to be removed to this <code>Agent</code>
	 * 
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified
	 *         <code>msnChatID</code>
	 */
	public boolean removeMsnChatID(String msnChatID) {
		return msnChatIDSet.remove(msnChatID);
	}

	/**
	 * Removes all of the msnChatIDs from this {@link Agent}. The msnChatIDs from <code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearMsnChatIDs() {
		msnChatIDSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>msnChatID</code>.
	 * 
	 * @param msnChatID The <code>msnChatID</code> whose presence in this <code>Agent</code> is to
	 *            be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>msnChatID</code>
	 */
	public boolean containsMsnChatID(String msnChatID) {
		return msnChatIDSet.contains(msnChatID);
	}

	/**
	 * Returns all tipJars.
	 * 
	 * @return Returns all tipJars.
	 */
	public List<Document> getAllTipJars() {
		return new ArrayList<Document>(tipJarSet);
	}

	/**
	 * Adds the specified <code>tipJar</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param tipJar The <code>tipJar</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>tipJar</code>
	 */
	public boolean addTipJar(Document tipJar) {
		return tipJarSet.add(tipJar);
	}

	/**
	 * Removes the specified <code>tipJar</code> to this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>tipJar</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param tipJar The <code>tipJar</code> to be removed to this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>tipJar</code>
	 */
	public boolean removeTipJar(Document tipJar) {
		return tipJarSet.remove(tipJar);
	}

	/**
	 * Removes all of the tipJars from this {@link Agent}. The tipJars from <code>Agent</code> will
	 * be empty after this call returns.
	 */
	public void clearTipJars() {
		tipJarSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>tipJar</code>
	 * 
	 * @param tipJar The <code>tipJar</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>tipJar</code>
	 */
	public boolean containsTipJar(Document tipJar) {
		return tipJarSet.contains(tipJar);
	}

	/**
	 * Return all weblogs.
	 * 
	 * @return Returns all weblogs.
	 */
	public List<Document> getAllWeblogs() {
		return new ArrayList<Document>(weblogSet);
	}

	/**
	 * Removes all of the weblogs from this {@link Agent}. The weblogs from <code>Agent</code> will
	 * be empty after this call returns.
	 */
	public void clearWeblogs() {
		weblogSet.clear();
	}

	/**
	 * Adds the specified <code>weblog</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param weblog The <code>weblog</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>weblog</code>
	 */
	public boolean addWeblog(Document weblog) {
		return weblogSet.add(weblog);
	}

	/**
	 * Removes the specified <code>weblog</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>weblog</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param weblog The <code>weblog</code> to be removed from this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>weblog</code>
	 */
	public boolean removeWeblog(Document weblog) {
		return weblogSet.remove(weblog);
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified weblog.
	 * 
	 * @param weblog The <code>weblog</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>weblog</code>
	 */
	public boolean containsWeblog(Document weblog) {
		return weblogSet.contains(weblog);
	}

	/**
	 * Returns all yahooChatIDs.
	 * 
	 * @return Returns all yahooChatIDs.
	 */
	public List<String> getAllYahooChatIDs() {
		return new ArrayList<String>(yahooChatIDSet);
	}

	/**
	 * Adds the specified <code>yahooChatID</code> to this {@link Agent} if it is not already
	 * present.
	 * 
	 * @param yahooChatID The <code>yahooChatID</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>yahooChatID</code>
	 */
	public boolean addYahooChatID(String yahooChatID) {
		return yahooChatIDSet.add(yahooChatID);
	}

	/**
	 * Removes all of the yahooChatIDs from this {@link Agent}. The yahooChatIDs from
	 * <code>Agent</code> will be empty after this call returns.
	 */
	public void clearYahooChatIDs() {
		yahooChatIDSet.clear();
	}

	/**
	 * Removes the specified <code>yahooChatID</code> from this {@link Agent}, if it is present.
	 * Returns <tt>true</tt> if this <code>Agent</code> contained the specified
	 * <code>yahooChatID</code> (or equivalently, if this <code>Agent</code> changed as a result of
	 * the call).
	 * 
	 * @param yahooChatID The <code>yahooChatID</code> to be removed from this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified
	 *         <code>yahooChatID</code>
	 */
	public boolean removeYahooChatID(String yahooChatID) {
		return yahooChatIDSet.remove(yahooChatID);
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>yahooChatID</code>.
	 * 
	 * @param yahooChatID The <code>yahooChatID</code> whose presence in this <code>Agent</code> is
	 *            to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>yahooChatID</code>
	 */
	public boolean containsYahooChatID(String yahooChatID) {
		return yahooChatIDSet.contains(yahooChatID);
	}

	/**
	 * @return Returns the birthday.
	 */
	public String getBirthday() {
		return birthday;
	}

	/**
	 * @param birthday The birthday to set.
	 */
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	/**
	 * @return the age.
	 */
	public String getAge() {
		return age;
	}

	/**
	 * @param age The age to set.
	 */
	public void setAge(String age) {
		this.age = age;
	}

	/**
	 * Return all skypeIDs.
	 * 
	 * @return Returns all skypeIDs.
	 */
	public List<String> getAllSkypeIDs() {
		return new ArrayList<String>(skypeIDSet);
	}

	/**
	 * Adds the specified <code>skypeID</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param skypeID The <code>skypeID</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>skypeID</code>
	 */
	public boolean addSkypeID(String skypeID) {
		return skypeIDSet.add(skypeID);
	}

	/**
	 * Removes the specified <code>skypeID</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>skypeID</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param skypeID The <code>skypeID</code> to be removed from this <code>Agent</code>.
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>skypeID</code>
	 */
	public boolean removeSkypeID(String skypeID) {
		return skypeIDSet.remove(skypeID);
	}

	/**
	 * Removes all of the skypeIDs from this {@link Agent}. The skypeIDs from <code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearSkypeIDs() {
		skypeIDSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>skypeID</code>.
	 * 
	 * @param skypeID The <code>skypeID</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>skypeID</code>
	 */
	public boolean containsSkypeID(String skypeID) {
		return skypeIDSet.contains(skypeID);
	}

	/**
	 * Returns all mades.
	 * 
	 * @return Returns all mades.
	 */
	public List<Thing> getAllMades() {
		return new ArrayList<Thing>(madeSet);
	}

	/**
	 * Adds the specified <code>made</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param made The <code>made</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>made</code>
	 */
	public boolean addMade(Thing made) {
		return madeSet.add(made);
	}

	/**
	 * Removes the specified <code>made</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>made</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param made The <code>made</code> to be removed from this <code>Agent</code> .
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>made</code>
	 */
	public boolean removeMade(Thing made) {
		return madeSet.remove(made);
	}

	/**
	 * Removes all mades from this {@link Agent}. The mades from <code>Agent</code> will be empty
	 * after this call returns.
	 */
	public void clearMades() {
		madeSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>made</code>
	 * 
	 * @param made The <code>made</code> whose presence in this <code>Agent</code> is to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>made</code>
	 */
	public boolean containsMade(Thing made) {
		return madeSet.contains(made);
	}

	/**
	 * @return the status.
	 */
	public String getStatus() {
		return status;
	}

	/**
	 * @param status The status to set.
	 */
	public void setStatus(String status) {
		this.status = status;
	}

	/**
	 * Returns all accounts.
	 * 
	 * @return Returns all accounts.
	 */
	public List<OnlineAccount> getAllAccounts() {
		return new ArrayList<OnlineAccount>(accountSet);
	}

	/**
	 * Adds the specified <code>account</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param account The <code>account</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>account</code>
	 */
	public boolean addAccount(OnlineAccount account) {
		return accountSet.add(account);
	}

	/**
	 * Removes the specified <code>account</code> to this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>account</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param account The <code>account</code> to be removed to this <code>Agent</code> .
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>account</code>
	 */
	public boolean removeAccount(Thing account) {
		return accountSet.remove(account);
	}

	/**
	 * Removes all accounts from this {@link Agent}. The accounts from <code>Agent</code> will be
	 * empty after this call returns.
	 */
	public void clearAccounts() {
		accountSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>account</code>
	 * 
	 * @param account The <code>account</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>account</code>
	 */
	public boolean containsAccount(Thing account) {
		return accountSet.contains(account);
	}

	/**
	 * Returns all openids.
	 * 
	 * @return Returns all openids.
	 */
	public List<Document> getAllOpenids() {
		return new ArrayList<Document>(openidSet);
	}

	/**
	 * Adds the specified <code>openid</code> to this {@link Agent} if it is not already present.
	 * 
	 * @param openid The <code>openid</code> to be added to this <code>Agent</code> .
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>openid</code>
	 */
	public boolean addOpenid(Document openid) {
		return openidSet.add(openid);
	}

	/**
	 * Removes the specified <code>openid</code> from this {@link Agent}, if it is present. Returns
	 * <tt>true</tt> if this <code>Agent</code> contained the specified <code>openid</code> (or
	 * equivalently, if this <code>Agent</code> changed as a result of the call).
	 * 
	 * @param openid The <code>openid</code> to be removed from this <code>Agent</code> .
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified <code>openid</code>
	 */
	public boolean removeOpenid(Thing openid) {
		return openidSet.remove(openid);
	}

	/**
	 * Removes all of the openids from this {@link Agent}. The openids from <code>Agent</code> will
	 * be empty after this call returns.
	 */
	public void clearOpenids() {
		openidSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>openid</code>
	 * 
	 * @param openid The <code>openid</code> whose presence in this <code>Agent</code> is to be
	 *            tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified <code>openid</code>
	 */
	public boolean containsOpenid(Document openid) {
		return openidSet.contains(openid);
	}

	/**
	 * Sets the <code>openid</code> from an {@link Agent}. First, all existing openids are removed,
	 * then this <code>openid</code> is added. If this <code>Agent</code> already contains the
	 * <code>openid</code>, the call leaves the <code>Agent</code> unchanged and returns
	 * <tt>false</tt>. The method also ensures that <code>Agent</code> never contains duplicate
	 * openids.
	 * 
	 * @param openid The <code>openid</code> to set.
	 * 
	 */
	public boolean setOpenid(Document openid) {
		if (!openidSet.contains(openid)) {
			openidSet.clear();
			return openidSet.add(openid);
		}
		return false;
	}

	/**
	 * Sets the <code>openid</code> value from an {@link Agent}. First, all existing openids are
	 * removed, then this <code>openid</code> value is added. If this <code>Agent</code> already
	 * contains the <code>openid</code> value, the call leaves the <code>Agent</code> unchanged and
	 * returns <tt>false</tt>. The method also ensures that <code>Agent</code> never contains
	 * duplicate openid values.
	 * 
	 * @param openId The <code>openid</code> to set.
	 * 
	 */
	public boolean setOpenid(String openId) {
		if (!openidSet.contains(new Document(openId))) {
			openidSet.clear();
			return openidSet.add(new Document(openId));
		}
		return false;
	}

	/**
	 * Returns the holdsAccount if this {@link Agent} contains the specified holdsAccount value
	 * 
	 * @param value The holdsAccount value to get
	 * @return the holdsAccount if this <code>Agent</code> contains the specified holdsAccount value
	 */
	public OnlineAccount getHoldsAccount(String value) {
		if (value == null)
			return null;
		OnlineAccount holdsAccount = new OnlineAccount(value);
		Iterator<OnlineAccount> iterator = holdsAccountSet.iterator();
		while (iterator.hasNext()) {
			OnlineAccount current = iterator.next();
			if (current.equals(holdsAccount)) {
				return current;
			}
		}
		return null;
	}

	/**
	 * Return all holdsAccounts.
	 * 
	 * @return Returns all holdsAccounts.
	 */
	public List<OnlineAccount> getAllHoldsAccounts() {
		return new ArrayList<OnlineAccount>(holdsAccountSet);
	}

	/**
	 * Adds the specified <code>holdsAccount</code> to this {@link Agent} if it is not already
	 * present.
	 * 
	 * @param holdsAccount The <code>holdsAccount</code> to be added to this <code>Agent</code>.
	 * @return <tt>true</tt> if the <code>Agent</code> did not already contain the specified
	 *         <code>holdsAccount</code>
	 */
	public boolean addHoldsAccount(OnlineAccount holdsAccount) {
		return holdsAccountSet.add(holdsAccount);
	}

	/**
	 * Removes the specified <code>holdsAccount</code> from this {@link Agent}, if it is present.
	 * Returns <tt>true</tt> if this <code>Agent</code> contained the specified
	 * <code>holdsAccount</code> (or equivalently, if this <code>Agent</code> changed as a result of
	 * the call).
	 * 
	 * @param holdsAccount The <code>holdsAccount</code> to be removed from this <code>Agent</code> .
	 * @return <tt>true</tt> if this <code>Agent</code> contained the specified
	 *         <code>holdsAccount</code>
	 */
	public boolean removeHoldsAccount(Thing holdsAccount) {
		return holdsAccountSet.remove(holdsAccount);
	}

	/**
	 * Removes all holdsAccounts from this {@link Agent}. The holdsAccounts from <code>Agent</code>
	 * will be empty after this call returns.
	 */
	public void clearHoldsAccounts() {
		holdsAccountSet.clear();
	}

	/**
	 * Returns <tt>true</tt> if this {@link Agent} contains the specified <code>holdsAccount</code>
	 * 
	 * @param holdsAccount The <code>holdsAccount</code> whose presence in this <code>Agent</code>
	 *            is to be tested.
	 * @return <tt>true</tt> if this <code>Agent</code> contains the specified
	 *         <code>holdsAccount</code>
	 */
	public boolean containsHoldsAccount(Thing holdsAccount) {
		return holdsAccountSet.contains(holdsAccount);
	}
}
